/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.florent37.github.com.expansionpanel;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ComponentParent;
import ohos.agp.components.StackLayout;
import ohos.agp.render.Canvas;
import ohos.app.Context;

/**
 * lipeiquan
 *
 * @since 2021-05-06
 */
public class ExpansionHeader extends StackLayout {


    int headerIndicatorId = 0;
    int expansionLayoutId = 0;
    boolean toggleOnClick = true;
    Component headerIndicator;
    ExpansionLayout expansionLayout;
    AnimatorProperty indicatorAnimator;
    private int headerRotationExpanded = 270;
    private int headerRotationCollapsed = 90;
    private boolean expansionLayoutInitialised = false;
    private DrawTask task;
    private long lastClickTime = 0;
    private boolean mCurWillExpand = false;

    public ExpansionHeader(Context context) {
        super(context);
    }

    public ExpansionHeader(Context context, AttrSet attrSet) {
        super(context, attrSet);

        if (task == null) {
            task = new DrawTask() {
                @Override
                public void onDraw(Component component, Canvas canvas) {

                }
            };
        }
        addDrawTask(task);
    }


    public ExpansionHeader(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
    }


    public void init(int expansion_layout, boolean expansion_toggleOnClick,
                     int expansion_headerIndicator, int expansion_headerIndicatorRotationExpanded,
                     int expansion_headerIndicatorRotationCollapsed) {

        this.toggleOnClick = expansion_toggleOnClick;
        this.expansionLayoutId = expansion_layout;
        this.headerIndicatorId = expansion_headerIndicator;
        setHeaderRotationExpanded(headerRotationExpanded);
        setHeaderRotationCollapsed(headerRotationCollapsed);
        setHeaderIndicatorId(headerIndicatorId);
        setExpansionLayoutId(expansionLayoutId);
        setToggleOnClick(toggleOnClick);


    }

    public void setHeaderRotationExpanded(int headerRotationExpanded) {
        this.headerRotationExpanded = headerRotationExpanded;
    }

    public void setHeaderRotationCollapsed(int headerRotationCollapsed) {
        this.headerRotationCollapsed = headerRotationCollapsed;
    }

    public boolean isToggleOnClick() {
        return toggleOnClick;
    }

    public void setToggleOnClick(boolean toggleOnClick) {
        this.toggleOnClick = toggleOnClick;
    }

    public void setHeaderIndicatorId(int headerIndicatorId) {
        this.headerIndicatorId = headerIndicatorId;
        if (headerIndicatorId != 0) {
            headerIndicator = findComponentById(headerIndicatorId);
            setExpansionHeaderIndicator(headerIndicator);
        }
    }

    public void setExpansionHeaderIndicator(Component headerIndicator) {
        this.headerIndicator = headerIndicator;

        //if not, the view will clip when rotate
//        if (headerIndicator != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
//            headerIndicator.setLayerType(LAYER_TYPE_SOFTWARE, null);
//        }

        setup();
    }

    public void setExpansionLayout(ExpansionLayout expansionLayout) {

        this.expansionLayout = expansionLayout;
        setup();
    }

    public void setExpansionLayoutId(int expansionLayoutId) {

        this.expansionLayoutId = expansionLayoutId;
        if (expansionLayoutId != 0) {
            ComponentParent componentParent = getComponentParent();
            if (componentParent instanceof ComponentContainer) {

                Component component = ((ComponentContainer) componentParent).findComponentById(expansionLayoutId);
                if (component instanceof ExpansionLayout) {

                    setExpansionLayout(((ExpansionLayout) component));
                }
            }
        }

    }


    private void setup() {
        if (expansionLayout != null && !expansionLayoutInitialised) {
            expansionLayout.addIndicatorListener(new ExpansionLayout.IndicatorListener() {
                @Override
                public void onStartedExpand(ExpansionLayout expansionLayout, boolean willExpand) {
                    onExpansionModifyView(willExpand);
                }
            });

            setClickedListener(new ClickedListener() {
                @Override
                public void onClick(Component component) {
                    if (System.currentTimeMillis() - lastClickTime < 400) {
                        return;
                    }
                    lastClickTime = System.currentTimeMillis();
                    if (toggleOnClick) {
                        expansionLayout.toggle(true);
                    }
                }
            });
            initialiseView(expansionLayout.isExpanded());
            expansionLayoutInitialised = true;
        }

    }

    //can be overriden
    protected void initialiseView(boolean isExpanded) {

        if (headerIndicator != null) {
            headerIndicator.setRotation(isExpanded ? headerRotationExpanded : headerRotationCollapsed);
        }
    }

    //can be overriden
    protected void onExpansionModifyView(boolean willExpand) {
        mCurWillExpand = willExpand;
        setSelected(willExpand);
        if (headerIndicator != null) {
            if (willExpand) {
                indicatorAnimator = headerIndicator.createAnimatorProperty();
                indicatorAnimator.rotate(headerRotationExpanded);
            } else {
                indicatorAnimator = headerIndicator.createAnimatorProperty();
                indicatorAnimator.rotate(headerRotationCollapsed);
            }
            headerIndicator.getContext().getUITaskDispatcher().delayDispatch(new Runnable() {
                @Override
                public void run() {
                    if(mCurWillExpand){
                        headerIndicator.setRotation(headerRotationExpanded);
                    }else {
                        headerIndicator.setRotation(headerRotationCollapsed);
                    }
                }
            },200);
            indicatorAnimator.start();
        }
    }

    public boolean isExpanded() {
        return expansionLayout != null && expansionLayout.isExpanded();
    }

    public void addListener(ExpansionLayout.Listener listener) {
        if (expansionLayout != null) {
            expansionLayout.addListener(listener);
        }
    }

    public void removeListener(ExpansionLayout.Listener listener) {
        if (expansionLayout != null) {
            expansionLayout.removeListener(listener);
        }
    }


}